home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / edm-v099.zip / ITEMS.QC < prev   
Text File  |  1996-10-09  |  31KB  |  1,399 lines

  1. void() W_SetCurrentAmmo;
  2. /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
  3. BE .8 .3 .4 IN COLOR */
  4.  
  5.  
  6. void() SUB_regen =
  7. {
  8.     self.model = self.mdl;        // restore original model
  9.     self.solid = SOLID_TRIGGER;    // allow it to be touched again
  10.     sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);    // play respawn sound
  11.     setorigin (self, self.origin);
  12. };
  13.  
  14.  
  15.  
  16. /*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
  17. prints a warning message when spawned
  18. */
  19. void() noclass =
  20. {
  21.     dprint ("noclass spawned at");
  22.     dprint (vtos(self.origin));
  23.     dprint ("\n");
  24.     remove (self);
  25. };
  26.  
  27.  
  28.  
  29. /*
  30. ============
  31. PlaceItem
  32.  
  33. plants the object on the floor
  34. ============
  35. */
  36. void() PlaceItem =
  37. {
  38.     local float    oldz;
  39.  
  40.     self.mdl = self.model;        // so it can be restored on respawn
  41.     self.flags = FL_ITEM;        // make extra wide
  42.     self.solid = SOLID_TRIGGER;
  43.     self.movetype = MOVETYPE_TOSS;    
  44.     self.velocity = '0 0 0';
  45.     self.origin_z = self.origin_z + 6;
  46.     oldz = self.origin_z;
  47.     if (!droptofloor())
  48.     {
  49.         dprint ("Bonus item fell out of level at ");
  50.         dprint (vtos(self.origin));
  51.         dprint ("\n");
  52.         remove(self);
  53.         return;
  54.     }
  55. };
  56.  
  57. /*
  58. ============
  59. StartItem
  60.  
  61. Sets the clipping size and plants the object on the floor
  62. ============
  63. */
  64. void() StartItem =
  65. {
  66.     self.nextthink = time + 0.2;    // items start after other solids
  67.     self.think = PlaceItem;
  68. };
  69.  
  70. /*
  71. =========================================================================
  72.  
  73. HEALTH BOX
  74.  
  75. =========================================================================
  76. */
  77. //
  78. // T_Heal: add health to an entity, limiting health to max_health
  79. // "ignore" will ignore max_health limit
  80. //
  81. float (entity e, float healamount, float ignore) T_Heal =
  82. {
  83.     if (e.health <= 0)
  84.         return 0;
  85.     if ((!ignore) && (e.health >= other.max_health))
  86.         return 0;
  87.     healamount = ceil(healamount);
  88.  
  89.     e.health = e.health + healamount;
  90.     if ((!ignore) && (e.health >= other.max_health))
  91.         e.health = other.max_health;
  92.         
  93.     if (e.health > 250)
  94.         e.health = 250;
  95.     return 1;
  96. };
  97.  
  98. /*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth
  99. Health box. Normally gives 25 points.
  100. Rotten box heals 5-10 points,
  101. megahealth will add 100 health, then 
  102. rot you down to your maximum health limit, 
  103. one point per second.
  104. */
  105.  
  106. float    H_ROTTEN = 1;
  107. float    H_MEGA = 2;
  108. .float    healamount, healtype;
  109. void() health_touch;
  110. void() item_megahealth_rot;
  111.  
  112. void() item_health =
  113. {    
  114.     self.touch = health_touch;
  115.  
  116.     if (self.spawnflags & H_ROTTEN)
  117.     {
  118.         precache_model("maps/b_bh10.bsp");
  119.  
  120.         precache_sound("items/r_item1.wav");
  121.         setmodel(self, "maps/b_bh10.bsp");
  122.         self.noise = "items/r_item1.wav";
  123.         self.healamount = 15;
  124.         self.healtype = 0;
  125.     }
  126.     else
  127.     if (self.spawnflags & H_MEGA)
  128.     {
  129.         precache_model("maps/b_bh100.bsp");
  130.         precache_sound("items/r_item2.wav");
  131.         setmodel(self, "maps/b_bh100.bsp");
  132.         self.noise = "items/r_item2.wav";
  133.         self.healamount = 100;
  134.         self.healtype = 2;
  135.     }
  136.     else
  137.     {
  138.         precache_model("maps/b_bh25.bsp");
  139.         precache_sound("items/health1.wav");
  140.         setmodel(self, "maps/b_bh25.bsp");
  141.         self.noise = "items/health1.wav";
  142.         self.healamount = 25;
  143.         self.healtype = 1;
  144.     }
  145.     setsize (self, '0 0 0', '32 32 56');
  146.     StartItem ();
  147. };
  148.  
  149.  
  150. void() health_touch =
  151. {
  152.     local    float amount;
  153.     local    string    s;
  154.     
  155.     if (other.classname != "player")
  156.         return;
  157.     
  158.     if (self.healtype == 2) // Megahealth?  Ignore max_health...
  159.     {
  160.         if (other.health >= 250)
  161.             return;
  162.         if (!T_Heal(other, self.healamount, 1))
  163.             return;
  164.     }
  165.     else
  166.     {
  167.         if (!T_Heal(other, self.healamount, 0))
  168.             return;
  169.     }
  170.     
  171.     sprint(other, "You receive ");
  172.     s = ftos(self.healamount);
  173.     sprint(other, s);
  174.     sprint(other, " health\n");
  175.     
  176. // health touch sound
  177.     sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  178.  
  179.     stuffcmd (other, "bf\n");
  180.     
  181.     self.model = string_null;
  182.     self.solid = SOLID_NOT;
  183.  
  184.     // Megahealth = rot down the player's super health
  185.     if (self.healtype == 2)
  186.     {
  187.         other.items = other.items | IT_SUPERHEALTH;
  188.         self.nextthink = time + 5;
  189.         self.think = item_megahealth_rot;
  190.         self.owner = other;
  191.     }
  192.     else
  193.     {
  194.                 if (deathmatch != 2 && deathmatch != 4 && deathmatch != 7 && deathmatch != 8)            // deathmatch 2 is the silly old rules
  195.         {
  196.             if (deathmatch)
  197.                 self.nextthink = time + 20;
  198.             self.think = SUB_regen;
  199.         }
  200.     }
  201.     
  202.     activator = other;
  203.     SUB_UseTargets();                // fire all targets / killtargets
  204. };    
  205.  
  206. void() item_megahealth_rot =
  207. {
  208.     other = self.owner;
  209.     
  210.     if (other.health > other.max_health)
  211.     {
  212.         other.health = other.health - 1;
  213.         self.nextthink = time + 1;
  214.         return;
  215.     }
  216.  
  217. // it is possible for a player to die and respawn between rots, so don't
  218. // just blindly subtract the flag off
  219.     other.items = other.items - (other.items & IT_SUPERHEALTH);
  220.     
  221.         if (deathmatch == 1 || deathmatch == 5 || deathmatch == 6)    // deathmatch 2 is silly old rules
  222.     {
  223.         self.nextthink = time + 20;
  224.         self.think = SUB_regen;
  225.     }
  226. };
  227.  
  228. /*
  229. ===============================================================================
  230.  
  231. ARMOR
  232.  
  233. ===============================================================================
  234. */
  235.  
  236. void() armor_touch;
  237.  
  238. void() armor_touch =
  239. {
  240.     local    float    type, value, bit;
  241.     
  242.     if (other.health <= 0)
  243.         return;
  244.     if (other.classname != "player")
  245.         return;
  246.  
  247.     if (self.classname == "item_armor1")
  248.     {
  249.         type = 0.3;
  250.         value = 100;
  251.         bit = IT_ARMOR1;
  252.     }
  253.     if (self.classname == "item_armor2")
  254.     {
  255.         type = 0.6;
  256.         value = 150;
  257.         bit = IT_ARMOR2;
  258.     }
  259.     if (self.classname == "item_armorInv")
  260.     {
  261.         type = 0.8;
  262.         value = 200;
  263.         bit = IT_ARMOR3;
  264.     }
  265.     if (other.armortype*other.armorvalue >= type*value)
  266.         return;
  267.         
  268.     other.armortype = type;
  269.     other.armorvalue = value;
  270.     other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
  271.  
  272.     self.solid = SOLID_NOT;
  273.     self.model = string_null;
  274.         if (deathmatch == 1 || deathmatch >= 5)
  275.         self.nextthink = time + 20;
  276.     self.think = SUB_regen;
  277.  
  278.     sprint(other, "You got armor\n");
  279. // armor touch sound
  280.     sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  281.     stuffcmd (other, "bf\n");
  282.     
  283.     activator = other;
  284.     SUB_UseTargets();                // fire all targets / killtargets
  285. };
  286.  
  287.  
  288. /*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32)
  289. */
  290.  
  291. void() item_armor1 =
  292. {
  293.     self.touch = armor_touch;
  294.     precache_model ("progs/armor.mdl");
  295.     setmodel (self, "progs/armor.mdl");
  296.     self.skin = 0;
  297.     setsize (self, '-16 -16 0', '16 16 56');
  298.     StartItem ();
  299. };
  300.  
  301. /*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32)
  302. */
  303.  
  304. void() item_armor2 =
  305. {
  306.     self.touch = armor_touch;
  307.     precache_model ("progs/armor.mdl");
  308.     setmodel (self, "progs/armor.mdl");
  309.     self.skin = 1;
  310.     setsize (self, '-16 -16 0', '16 16 56');
  311.     StartItem ();
  312. };
  313.  
  314. /*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32)
  315. */
  316.  
  317. void() item_armorInv =
  318. {
  319.     self.touch = armor_touch;
  320.     precache_model ("progs/armor.mdl");
  321.     setmodel (self, "progs/armor.mdl");
  322.     self.skin = 2;
  323.     setsize (self, '-16 -16 0', '16 16 56');
  324.     StartItem ();
  325. };
  326.  
  327. /*
  328. ===============================================================================
  329.  
  330. WEAPONS
  331.  
  332. ===============================================================================
  333. */
  334.  
  335. void() bound_other_ammo =
  336. {
  337.     if (other.ammo_shells > 100)
  338.         other.ammo_shells = 100;
  339.     if (other.ammo_nails > 200)
  340.         other.ammo_nails = 200;
  341.     if (other.ammo_rockets > 100)
  342.         other.ammo_rockets = 100;        
  343.     if (other.ammo_cells > 100)
  344.         other.ammo_cells = 100;        
  345. };
  346.  
  347.  
  348. float(float w) RankForWeapon =
  349. {
  350.     if (w == IT_LIGHTNING)
  351.         return 1;
  352.     if (w == IT_ROCKET_LAUNCHER)
  353.         return 2;
  354.     if (w == IT_SUPER_NAILGUN)
  355.         return 3;
  356.     if (w == IT_GRENADE_LAUNCHER)
  357.         return 4;
  358.     if (w == IT_SUPER_SHOTGUN)
  359.         return 5;
  360.     if (w == IT_NAILGUN)
  361.         return 6;
  362.     return 7;
  363. };
  364.  
  365. /*
  366. =============
  367. Deathmatch_Weapon
  368.  
  369. Deathmatch weapon change rules for picking up a weapon
  370.  
  371. .float        ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
  372. =============
  373. */
  374. void(float old, float new) Deathmatch_Weapon =
  375. {
  376.     local float or, nr;
  377.  
  378. // change self.weapon if desired
  379.     or = RankForWeapon (self.weapon);
  380.     nr = RankForWeapon (new);
  381.     if ( nr < or )
  382.         self.weapon = new;
  383. };
  384.  
  385. /*
  386. =============
  387. weapon_touch
  388. =============
  389. */
  390. float() W_BestWeapon;
  391.  
  392. void() weapon_touch =
  393. {
  394.     local    float    hadammo, best, new, old;
  395.     local    entity    stemp;
  396.     local    float    leave;
  397.  
  398.     if (!(other.flags & FL_CLIENT))
  399.         return;
  400.  
  401. // if the player was using his best weapon, change up to the new one if better        
  402.     stemp = self;
  403.     self = other;
  404.     best = W_BestWeapon();
  405.     self = stemp;
  406.  
  407.         if (deathmatch == 2 || deathmatch == 4 || deathmatch == 6 || deathmatch == 8 || coop)
  408.         leave = 1;
  409.     else
  410.         leave = 0;
  411.     
  412.     if (self.classname == "weapon_nailgun")
  413.     {
  414.                 if ((leave || deathmatch == 5) && (other.items & IT_NAILGUN) )
  415.             return;
  416.         hadammo = other.ammo_nails;            
  417.         new = IT_NAILGUN;
  418.                 if (deathmatch == 4)
  419.                         other.ammo_nails = other.ammo_nails + 60;
  420.                 else
  421.                         other.ammo_nails = other.ammo_nails + 30;
  422.     }
  423.     else if (self.classname == "weapon_supernailgun")
  424.     {
  425.                 if ((leave || deathmatch == 5) && (other.items & IT_SUPER_NAILGUN) )
  426.             return;
  427.         hadammo = other.ammo_rockets;            
  428.         new = IT_SUPER_NAILGUN;
  429.                 if (deathmatch == 4)
  430.                         other.ammo_nails = other.ammo_nails + 60;
  431.                 else
  432.                         other.ammo_nails = other.ammo_nails + 30;
  433.     }
  434.     else if (self.classname == "weapon_supershotgun")
  435.     {
  436.                 if ((leave || deathmatch == 5) && (other.items & IT_SUPER_SHOTGUN) )
  437.             return;
  438.         hadammo = other.ammo_rockets;            
  439.         new = IT_SUPER_SHOTGUN;
  440.                 if (deathmatch == 4)
  441.                         other.ammo_shells = other.ammo_shells + 20;
  442.                 else
  443.                         other.ammo_shells = other.ammo_shells + 5;
  444.     }
  445.     else if (self.classname == "weapon_rocketlauncher")
  446.     {
  447.                 if ((leave || deathmatch == 5) && (other.items & IT_ROCKET_LAUNCHER) )
  448.             return;
  449.         hadammo = other.ammo_rockets;            
  450.         new = IT_ROCKET_LAUNCHER;
  451.                 if (deathmatch == 4)
  452.                         other.ammo_rockets = other.ammo_rockets + 10;
  453.                 else
  454.                         other.ammo_rockets = other.ammo_rockets + 5;
  455.     }
  456.     else if (self.classname == "weapon_grenadelauncher")
  457.     {
  458.                 if ((leave || deathmatch == 5) && (other.items & IT_GRENADE_LAUNCHER) )
  459.             return;
  460.         hadammo = other.ammo_rockets;            
  461.         new = IT_GRENADE_LAUNCHER;
  462.                 if (deathmatch == 4)
  463.                         other.ammo_rockets = other.ammo_rockets + 10;
  464.                 else
  465.                         other.ammo_rockets = other.ammo_rockets + 5;
  466.     }
  467.     else if (self.classname == "weapon_lightning")
  468.     {
  469.                 if ((leave || deathmatch == 5) && (other.items & IT_LIGHTNING) )
  470.             return;
  471.         hadammo = other.ammo_rockets;            
  472.         new = IT_LIGHTNING;
  473.                 if (deathmatch == 4)
  474.                         other.ammo_cells = other.ammo_cells + 30;
  475.                 else
  476.                         other.ammo_cells = other.ammo_cells + 15;
  477.     }
  478.     else
  479.         objerror ("weapon_touch: unknown classname");
  480.  
  481.     sprint (other, "You got the ");
  482.     sprint (other, self.netname);
  483.     sprint (other, "\n");
  484. // weapon touch sound
  485.     sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  486.     stuffcmd (other, "bf\n");
  487.  
  488.     bound_other_ammo ();
  489.  
  490. // change to the weapon
  491.     old = other.items;
  492.     other.items = other.items | new;
  493.     
  494.     stemp = self;
  495.     self = other;
  496.  
  497.     if (!deathmatch)
  498.         self.weapon = new;
  499.     else
  500.         Deathmatch_Weapon (old, new);
  501.  
  502.     W_SetCurrentAmmo();
  503.  
  504.     self = stemp;
  505.  
  506.     if (leave)
  507.         return;
  508.  
  509. // remove it in single player, or setup for respawning in deathmatch
  510.     self.model = string_null;
  511.     self.solid = SOLID_NOT;
  512.         if (deathmatch == 1 || deathmatch == 5 || deathmatch == 7)
  513.         self.nextthink = time + 30;
  514.     self.think = SUB_regen;
  515.     
  516.     activator = other;
  517.     SUB_UseTargets();                // fire all targets / killtargets
  518. };
  519.  
  520.  
  521. /*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32)
  522. */
  523.  
  524. void() weapon_supershotgun =
  525. {
  526.     precache_model ("progs/g_shot.mdl");
  527.     setmodel (self, "progs/g_shot.mdl");
  528.     self.weapon = IT_SUPER_SHOTGUN;
  529.     self.netname = "Double-barrelled Shotgun";
  530.     self.touch = weapon_touch;
  531.     setsize (self, '-16 -16 0', '16 16 56');
  532.     StartItem ();
  533. };
  534.  
  535. /*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  536. */
  537.  
  538. void() weapon_nailgun =
  539. {
  540.     precache_model ("progs/g_nail.mdl");
  541.     setmodel (self, "progs/g_nail.mdl");
  542.     self.weapon = IT_NAILGUN;
  543.     self.netname = "nailgun";
  544.     self.touch = weapon_touch;
  545.     setsize (self, '-16 -16 0', '16 16 56');
  546.     StartItem ();
  547. };
  548.  
  549. /*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  550. */
  551.  
  552. void() weapon_supernailgun =
  553. {
  554.     precache_model ("progs/g_nail2.mdl");
  555.     setmodel (self, "progs/g_nail2.mdl");
  556.     self.weapon = IT_SUPER_NAILGUN;
  557.     self.netname = "Super Nailgun";
  558.     self.touch = weapon_touch;
  559.     setsize (self, '-16 -16 0', '16 16 56');
  560.     StartItem ();
  561. };
  562.  
  563. /*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  564. */
  565.  
  566. void() weapon_grenadelauncher =
  567. {
  568.     precache_model ("progs/g_rock.mdl");
  569.     setmodel (self, "progs/g_rock.mdl");
  570.     self.weapon = 3;
  571.     self.netname = "Grenade Launcher";
  572.     self.touch = weapon_touch;
  573.     setsize (self, '-16 -16 0', '16 16 56');
  574.     StartItem ();
  575. };
  576.  
  577. /*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  578. */
  579.  
  580. void() weapon_rocketlauncher =
  581. {
  582.     precache_model ("progs/g_rock2.mdl");
  583.     setmodel (self, "progs/g_rock2.mdl");
  584.     self.weapon = 3;
  585.     self.netname = "Rocket Launcher";
  586.     self.touch = weapon_touch;
  587.     setsize (self, '-16 -16 0', '16 16 56');
  588.     StartItem ();
  589. };
  590.  
  591.  
  592. /*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
  593. */
  594.  
  595. void() weapon_lightning =
  596. {
  597.     precache_model ("progs/g_light.mdl");
  598.     setmodel (self, "progs/g_light.mdl");
  599.     self.weapon = 3;
  600.     self.netname = "Thunderbolt";
  601.     self.touch = weapon_touch;
  602.     setsize (self, '-16 -16 0', '16 16 56');
  603.     StartItem ();
  604. };
  605.  
  606.  
  607. /*
  608. ===============================================================================
  609.  
  610. AMMO
  611.  
  612. ===============================================================================
  613. */
  614.  
  615. void() ammo_touch =
  616. {
  617. local entity    stemp;
  618. local float        best;
  619.  
  620.     if (other.classname != "player")
  621.         return;
  622.     if (other.health <= 0)
  623.         return;
  624.  
  625. // if the player was using his best weapon, change up to the new one if better        
  626.     stemp = self;
  627.     self = other;
  628.     best = W_BestWeapon();
  629.     self = stemp;
  630.  
  631.  
  632. // shotgun
  633.     if (self.weapon == 1)
  634.     {
  635.         if (other.ammo_shells >= 100)
  636.             return;
  637.         other.ammo_shells = other.ammo_shells + self.aflag;
  638.     }
  639.  
  640. // spikes
  641.     if (self.weapon == 2)
  642.     {
  643.         if (other.ammo_nails >= 200)
  644.             return;
  645.         other.ammo_nails = other.ammo_nails + self.aflag;
  646.     }
  647.  
  648. //    rockets
  649.     if (self.weapon == 3)
  650.     {
  651.         if (other.ammo_rockets >= 100)
  652.             return;
  653.         other.ammo_rockets = other.ammo_rockets + self.aflag;
  654.     }
  655.  
  656. //    cells
  657.     if (self.weapon == 4)
  658.     {
  659.         if (other.ammo_cells >= 100)
  660.             return;
  661.         other.ammo_cells = other.ammo_cells + self.aflag;
  662.     }
  663.  
  664.     bound_other_ammo ();
  665.     
  666.     sprint (other, "You got the ");
  667.     sprint (other, self.netname);
  668.     sprint (other, "\n");
  669. // ammo touch sound
  670.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  671.     stuffcmd (other, "bf\n");
  672.  
  673. // change to a better weapon if appropriate
  674.  
  675.     if ( other.weapon == best )
  676.     {
  677.         stemp = self;
  678.         self = other;
  679.         self.weapon = W_BestWeapon();
  680.         W_SetCurrentAmmo ();
  681.         self = stemp;
  682.     }
  683.  
  684. // if changed current ammo, update it
  685.     stemp = self;
  686.     self = other;
  687.     W_SetCurrentAmmo();
  688.     self = stemp;
  689.  
  690. // remove it in single player, or setup for respawning in deathmatch
  691.     self.model = string_null;
  692.     self.solid = SOLID_NOT;
  693.         if (deathmatch == 1 || deathmatch >= 5)
  694.         self.nextthink = time + 30;
  695.     self.think = SUB_regen;
  696.  
  697.     activator = other;
  698.     SUB_UseTargets();                // fire all targets / killtargets
  699. };
  700.  
  701.  
  702.  
  703.  
  704. float WEAPON_BIG2 = 1;
  705.  
  706. /*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big
  707. */
  708.  
  709. void() item_shells =
  710. {
  711.     self.touch = ammo_touch;
  712.  
  713.     if (self.spawnflags & WEAPON_BIG2)
  714.     {
  715.         precache_model ("maps/b_shell1.bsp");
  716.         setmodel (self, "maps/b_shell1.bsp");
  717.         self.aflag = 40;
  718.     }
  719.     else
  720.     {
  721.         precache_model ("maps/b_shell0.bsp");
  722.         setmodel (self, "maps/b_shell0.bsp");
  723.         self.aflag = 20;
  724.     }
  725.     self.weapon = 1;
  726.     self.netname = "shells";
  727.     setsize (self, '0 0 0', '32 32 56');
  728.     StartItem ();
  729. };
  730.  
  731. /*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big
  732. */
  733.  
  734. void() item_spikes =
  735. {
  736.     self.touch = ammo_touch;
  737.  
  738.     if (self.spawnflags & WEAPON_BIG2)
  739.     {
  740.         precache_model ("maps/b_nail1.bsp");
  741.         setmodel (self, "maps/b_nail1.bsp");
  742.         self.aflag = 50;
  743.     }
  744.     else
  745.     {
  746.         precache_model ("maps/b_nail0.bsp");
  747.         setmodel (self, "maps/b_nail0.bsp");
  748.         self.aflag = 25;
  749.     }
  750.     self.weapon = 2;
  751.     self.netname = "nails";
  752.     setsize (self, '0 0 0', '32 32 56');
  753.     StartItem ();
  754. };
  755.  
  756. /*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big
  757. */
  758.  
  759. void() item_rockets =
  760. {
  761.     self.touch = ammo_touch;
  762.  
  763.     if (self.spawnflags & WEAPON_BIG2)
  764.     {
  765.         precache_model ("maps/b_rock1.bsp");
  766.         setmodel (self, "maps/b_rock1.bsp");
  767.         self.aflag = 10;
  768.     }
  769.     else
  770.     {
  771.         precache_model ("maps/b_rock0.bsp");
  772.         setmodel (self, "maps/b_rock0.bsp");
  773.         self.aflag = 5;
  774.     }
  775.     self.weapon = 3;
  776.     self.netname = "rockets";
  777.     setsize (self, '0 0 0', '32 32 56');
  778.     StartItem ();
  779. };
  780.  
  781.  
  782. /*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big
  783. */
  784.  
  785. void() item_cells =
  786. {
  787.     self.touch = ammo_touch;
  788.  
  789.     if (self.spawnflags & WEAPON_BIG2)
  790.     {
  791.         precache_model ("maps/b_batt1.bsp");
  792.         setmodel (self, "maps/b_batt1.bsp");
  793.         self.aflag = 12;
  794.     }
  795.     else
  796.     {
  797.         precache_model ("maps/b_batt0.bsp");
  798.         setmodel (self, "maps/b_batt0.bsp");
  799.         self.aflag = 6;
  800.     }
  801.     self.weapon = 4;
  802.     self.netname = "cells";
  803.     setsize (self, '0 0 0', '32 32 56');
  804.     StartItem ();
  805. };
  806.  
  807.  
  808. /*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big
  809. DO NOT USE THIS!!!! IT WILL BE REMOVED!
  810. */
  811.  
  812. float WEAPON_SHOTGUN = 1;
  813. float WEAPON_ROCKET = 2;
  814. float WEAPON_SPIKES = 4;
  815. float WEAPON_BIG = 8;
  816. void() item_weapon =
  817. {
  818.     self.touch = ammo_touch;
  819.  
  820.     if (self.spawnflags & WEAPON_SHOTGUN)
  821.     {
  822.         if (self.spawnflags & WEAPON_BIG)
  823.         {
  824.             precache_model ("maps/b_shell1.bsp");
  825.             setmodel (self, "maps/b_shell1.bsp");
  826.             self.aflag = 40;
  827.         }
  828.         else
  829.         {
  830.             precache_model ("maps/b_shell0.bsp");
  831.             setmodel (self, "maps/b_shell0.bsp");
  832.             self.aflag = 20;
  833.         }
  834.         self.weapon = 1;
  835.         self.netname = "shells";
  836.     }
  837.  
  838.     if (self.spawnflags & WEAPON_SPIKES)
  839.     {
  840.         if (self.spawnflags & WEAPON_BIG)
  841.         {
  842.             precache_model ("maps/b_nail1.bsp");
  843.             setmodel (self, "maps/b_nail1.bsp");
  844.             self.aflag = 40;
  845.         }
  846.         else
  847.         {
  848.             precache_model ("maps/b_nail0.bsp");
  849.             setmodel (self, "maps/b_nail0.bsp");
  850.             self.aflag = 20;
  851.         }
  852.         self.weapon = 2;
  853.         self.netname = "spikes";
  854.     }
  855.  
  856.     if (self.spawnflags & WEAPON_ROCKET)
  857.     {
  858.         if (self.spawnflags & WEAPON_BIG)
  859.         {
  860.             precache_model ("maps/b_rock1.bsp");
  861.             setmodel (self, "maps/b_rock1.bsp");
  862.             self.aflag = 10;
  863.         }
  864.         else
  865.         {
  866.             precache_model ("maps/b_rock0.bsp");
  867.             setmodel (self, "maps/b_rock0.bsp");
  868.             self.aflag = 5;
  869.         }
  870.         self.weapon = 3;
  871.         self.netname = "rockets";
  872.     }
  873.     
  874.     setsize (self, '0 0 0', '32 32 56');
  875.     StartItem ();
  876. };
  877.  
  878.  
  879. /*
  880. ===============================================================================
  881.  
  882. KEYS
  883.  
  884. ===============================================================================
  885. */
  886.  
  887. void() key_touch =
  888. {
  889. local entity    stemp;
  890. local float        best;
  891.  
  892.     if (other.classname != "player")
  893.         return;
  894.     if (other.health <= 0)
  895.         return;
  896.     if (other.items & self.items)
  897.         return;
  898.  
  899.     sprint (other, "You got the ");
  900.     sprint (other, self.netname);
  901.     sprint (other,"\n");
  902.  
  903.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  904.     stuffcmd (other, "bf\n");
  905.     other.items = other.items | self.items;
  906.  
  907.     if (!coop)
  908.     {    
  909.         self.solid = SOLID_NOT;
  910.         self.model = string_null;
  911.     }
  912.  
  913.     activator = other;
  914.     SUB_UseTargets();                // fire all targets / killtargets
  915. };
  916.  
  917.  
  918. void() key_setsounds =
  919. {
  920.     if (world.worldtype == 0)
  921.     {
  922.         precache_sound ("misc/medkey.wav");
  923.         self.noise = "misc/medkey.wav";
  924.     }
  925.     if (world.worldtype == 1)
  926.     {
  927.         precache_sound ("misc/runekey.wav");
  928.         self.noise = "misc/runekey.wav";
  929.     }
  930.     if (world.worldtype == 2)
  931.     {
  932.         precache_sound2 ("misc/basekey.wav");
  933.         self.noise = "misc/basekey.wav";
  934.     }
  935. };
  936.  
  937. /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32)
  938. SILVER key
  939. In order for keys to work
  940. you MUST set your maps
  941. worldtype to one of the
  942. following:
  943. 0: medieval
  944. 1: metal
  945. 2: base
  946. */
  947.  
  948. void() item_key1 =
  949. {
  950.     if (world.worldtype == 0)
  951.     {
  952.         precache_model ("progs/w_s_key.mdl");
  953.         setmodel (self, "progs/w_s_key.mdl");
  954.         self.netname = "silver key";
  955.     }
  956.     else if (world.worldtype == 1)
  957.     {
  958.         precache_model ("progs/m_s_key.mdl");
  959.         setmodel (self, "progs/m_s_key.mdl");
  960.         self.netname = "silver runekey";
  961.     }
  962.     else if (world.worldtype == 2)
  963.     {
  964.         precache_model2 ("progs/b_s_key.mdl");
  965.         setmodel (self, "progs/b_s_key.mdl");
  966.         self.netname = "silver keycard";
  967.     }
  968.     key_setsounds();
  969.     self.touch = key_touch;
  970.     self.items = IT_KEY1;
  971.     setsize (self, '-16 -16 -24', '16 16 32');
  972.     StartItem ();
  973. };
  974.  
  975. /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32)
  976. GOLD key
  977. In order for keys to work
  978. you MUST set your maps
  979. worldtype to one of the
  980. following:
  981. 0: medieval
  982. 1: metal
  983. 2: base
  984. */
  985.  
  986. void() item_key2 =
  987. {
  988.     if (world.worldtype == 0)
  989.     {
  990.         precache_model ("progs/w_g_key.mdl");
  991.         setmodel (self, "progs/w_g_key.mdl");
  992.         self.netname = "gold key";
  993.     }
  994.     if (world.worldtype == 1)
  995.     {
  996.         precache_model ("progs/m_g_key.mdl");
  997.         setmodel (self, "progs/m_g_key.mdl");
  998.         self.netname = "gold runekey";
  999.     }
  1000.     if (world.worldtype == 2)
  1001.     {
  1002.         precache_model2 ("progs/b_g_key.mdl");
  1003.         setmodel (self, "progs/b_g_key.mdl");
  1004.         self.netname = "gold keycard";
  1005.     }
  1006.     key_setsounds();
  1007.     self.touch = key_touch;
  1008.     self.items = IT_KEY2;
  1009.     setsize (self, '-16 -16 -24', '16 16 32');
  1010.     StartItem ();
  1011. };
  1012.  
  1013.  
  1014.  
  1015. /*
  1016. ===============================================================================
  1017.  
  1018. END OF LEVEL RUNES
  1019.  
  1020. ===============================================================================
  1021. */
  1022.  
  1023. void() sigil_touch =
  1024. {
  1025. local entity    stemp;
  1026. local float        best;
  1027.  
  1028.     if (other.classname != "player")
  1029.         return;
  1030.     if (other.health <= 0)
  1031.         return;
  1032.  
  1033.     centerprint (other, "You got the rune!");
  1034.  
  1035.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1036.     stuffcmd (other, "bf\n");
  1037.     self.solid = SOLID_NOT;
  1038.     self.model = string_null;
  1039.     serverflags = serverflags | (self.spawnflags & 15);
  1040.     self.classname = "";        // so rune doors won't find it
  1041.     
  1042.     activator = other;
  1043.     SUB_UseTargets();                // fire all targets / killtargets
  1044. };
  1045.  
  1046.  
  1047. /*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4
  1048. End of level sigil, pick up to end episode and return to jrstart.
  1049. */
  1050.  
  1051. void() item_sigil =
  1052. {
  1053.     if (!self.spawnflags)
  1054.         objerror ("no spawnflags");
  1055.  
  1056.     precache_sound ("misc/runekey.wav");
  1057.     self.noise = "misc/runekey.wav";
  1058.  
  1059.     if (self.spawnflags & 1)
  1060.     {
  1061.         precache_model ("progs/end1.mdl");
  1062.         setmodel (self, "progs/end1.mdl");
  1063.     }
  1064.     if (self.spawnflags & 2)
  1065.     {
  1066.         precache_model2 ("progs/end2.mdl");
  1067.         setmodel (self, "progs/end2.mdl");
  1068.     }
  1069.     if (self.spawnflags & 4)
  1070.     {
  1071.         precache_model2 ("progs/end3.mdl");
  1072.         setmodel (self, "progs/end3.mdl");
  1073.     }
  1074.     if (self.spawnflags & 8)
  1075.     {
  1076.         precache_model2 ("progs/end4.mdl");
  1077.         setmodel (self, "progs/end4.mdl");
  1078.     }
  1079.     
  1080.     self.touch = sigil_touch;
  1081.     setsize (self, '-16 -16 -24', '16 16 32');
  1082.     StartItem ();
  1083. };
  1084.  
  1085. /*
  1086. ===============================================================================
  1087.  
  1088. POWERUPS
  1089.  
  1090. ===============================================================================
  1091. */
  1092.  
  1093. void() powerup_touch;
  1094.  
  1095.  
  1096. void() powerup_touch =
  1097. {
  1098. local entity    stemp;
  1099. local float        best;
  1100.  
  1101.     if (other.classname != "player")
  1102.         return;
  1103.     if (other.health <= 0)
  1104.         return;
  1105.  
  1106.     sprint (other, "You got the ");
  1107.     sprint (other, self.netname);
  1108.     sprint (other,"\n");
  1109.  
  1110.     if (deathmatch)
  1111.     {
  1112.         self.mdl = self.model;
  1113.         
  1114.         if ((self.classname == "item_artifact_invulnerability") ||
  1115.             (self.classname == "item_artifact_invisibility"))
  1116.             self.nextthink = time + 60*5;
  1117.         else
  1118.             self.nextthink = time + 60;
  1119.         
  1120.         self.think = SUB_regen;
  1121.     }    
  1122.  
  1123.     sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  1124.     stuffcmd (other, "bf\n");
  1125.     self.solid = SOLID_NOT;
  1126.     other.items = other.items | self.items;
  1127.     self.model = string_null;
  1128.  
  1129. // do the apropriate action
  1130.     if (self.classname == "item_artifact_envirosuit")
  1131.     {
  1132.         other.rad_time = 1;
  1133.         other.radsuit_finished = time + 30;
  1134.     }
  1135.     
  1136.     if (self.classname == "item_artifact_invulnerability")
  1137.     {
  1138.         other.invincible_time = 1;
  1139.         other.invincible_finished = time + 30;
  1140.     }
  1141.     
  1142.     if (self.classname == "item_artifact_invisibility")
  1143.     {
  1144.         other.invisible_time = 1;
  1145.         other.invisible_finished = time + 30;
  1146.     }
  1147.  
  1148.     if (self.classname == "item_artifact_super_damage")
  1149.     {
  1150.         other.super_time = 1;
  1151.         other.super_damage_finished = time + 30;
  1152.     }    
  1153.  
  1154.     activator = other;
  1155.     SUB_UseTargets();                // fire all targets / killtargets
  1156. };
  1157.  
  1158.  
  1159.  
  1160. /*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32)
  1161. Player is invulnerable for 30 seconds
  1162. */
  1163. void() item_artifact_invulnerability =
  1164. {
  1165.     self.touch = powerup_touch;
  1166.  
  1167.     precache_model ("progs/invulner.mdl");
  1168.     precache_sound ("items/protect.wav");
  1169.     precache_sound ("items/protect2.wav");
  1170.     precache_sound ("items/protect3.wav");
  1171.     self.noise = "items/protect.wav";
  1172.     setmodel (self, "progs/invulner.mdl");
  1173.     self.netname = "Pentagram of Protection";
  1174.     self.items = IT_INVULNERABILITY;
  1175.     setsize (self, '-16 -16 -24', '16 16 32');
  1176.     StartItem ();
  1177. };
  1178.  
  1179. /*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32)
  1180. Player takes no damage from water or slime for 30 seconds
  1181. */
  1182. void() item_artifact_envirosuit =
  1183. {
  1184.     self.touch = powerup_touch;
  1185.  
  1186.     precache_model ("progs/suit.mdl");
  1187.     precache_sound ("items/suit.wav");
  1188.     precache_sound ("items/suit2.wav");
  1189.     self.noise = "items/suit.wav";
  1190.     setmodel (self, "progs/suit.mdl");
  1191.     self.netname = "Biosuit";
  1192.     self.items = IT_SUIT;
  1193.     setsize (self, '-16 -16 -24', '16 16 32');
  1194.     StartItem ();
  1195. };
  1196.  
  1197.  
  1198. /*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32)
  1199. Player is invisible for 30 seconds
  1200. */
  1201. void() item_artifact_invisibility =
  1202. {
  1203.     self.touch = powerup_touch;
  1204.  
  1205.     precache_model ("progs/invisibl.mdl");
  1206.     precache_sound ("items/inv1.wav");
  1207.     precache_sound ("items/inv2.wav");
  1208.     precache_sound ("items/inv3.wav");
  1209.     self.noise = "items/inv1.wav";
  1210.     setmodel (self, "progs/invisibl.mdl");
  1211.     self.netname = "Ring of Shadows";
  1212.     self.items = IT_INVISIBILITY;
  1213.     setsize (self, '-16 -16 -24', '16 16 32');
  1214.     StartItem ();
  1215. };
  1216.  
  1217.  
  1218. /*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32)
  1219. The next attack from the player will do 4x damage
  1220. */
  1221. void() item_artifact_super_damage =
  1222. {
  1223.     self.touch = powerup_touch;
  1224.  
  1225.     precache_model ("progs/quaddama.mdl");
  1226.     precache_sound ("items/damage.wav");
  1227.     precache_sound ("items/damage2.wav");
  1228.     precache_sound ("items/damage3.wav");
  1229.     self.noise = "items/damage.wav";
  1230.     setmodel (self, "progs/quaddama.mdl");
  1231.     self.netname = "Quad Damage";
  1232.     self.items = IT_QUAD;
  1233.     setsize (self, '-16 -16 -24', '16 16 32');
  1234.     StartItem ();
  1235. };
  1236.  
  1237.  
  1238.  
  1239. /*
  1240. ===============================================================================
  1241.  
  1242. PLAYER BACKPACKS
  1243.  
  1244. ===============================================================================
  1245. */
  1246.  
  1247. void() BackpackTouch =
  1248. {
  1249.     local string    s;
  1250.     local    float    best, old, new;
  1251.     local        entity    stemp;
  1252.     local    float    acount;
  1253.     
  1254.     if (other.classname != "player")
  1255.         return;
  1256.     if (other.health <= 0)
  1257.         return;
  1258.  
  1259.     acount = 0;
  1260.     sprint (other, "You get ");
  1261.  
  1262.     if (self.items)
  1263.         if ((other.items & self.items) == 0)
  1264.         {
  1265.             acount = 1;
  1266.             sprint (other, "the ");
  1267.             sprint (other, self.netname);
  1268.         }
  1269.  
  1270. // if the player was using his best weapon, change up to the new one if better        
  1271.     stemp = self;
  1272.     self = other;
  1273.     best = W_BestWeapon();
  1274.     self = stemp;
  1275.  
  1276. // change weapons
  1277.     other.ammo_shells = other.ammo_shells + self.ammo_shells;
  1278.     other.ammo_nails = other.ammo_nails + self.ammo_nails;
  1279.     other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1280.     other.ammo_cells = other.ammo_cells + self.ammo_cells;
  1281.  
  1282.     new = self.items;
  1283.     if (!new)
  1284.         new = other.weapon;
  1285.     old = other.items;
  1286.     other.items = other.items | new;
  1287.     
  1288.     bound_other_ammo ();
  1289.  
  1290.     if (self.ammo_shells)
  1291.     {
  1292.         if (acount)
  1293.             sprint(other, ", ");
  1294.         acount = 1;
  1295.         s = ftos(self.ammo_shells);
  1296.         sprint (other, s);
  1297.         sprint (other, " shells");
  1298.     }
  1299.     if (self.ammo_nails)
  1300.     {
  1301.         if (acount)
  1302.             sprint(other, ", ");
  1303.         acount = 1;
  1304.         s = ftos(self.ammo_nails);
  1305.         sprint (other, s);
  1306.         sprint (other, " nails");
  1307.     }
  1308.     if (self.ammo_rockets)
  1309.     {
  1310.         if (acount)
  1311.             sprint(other, ", ");
  1312.         acount = 1;
  1313.         s = ftos(self.ammo_rockets);
  1314.         sprint (other, s);
  1315.         sprint (other, " rockets");
  1316.     }
  1317.     if (self.ammo_cells)
  1318.     {
  1319.         if (acount)
  1320.             sprint(other, ", ");
  1321.         acount = 1;
  1322.         s = ftos(self.ammo_cells);
  1323.         sprint (other, s);
  1324.         sprint (other, " cells");
  1325.     }
  1326.     
  1327.     sprint (other, "\n");
  1328. // backpack touch sound
  1329.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1330.     stuffcmd (other, "bf\n");
  1331.  
  1332. // remove the backpack, change self to the player
  1333.     remove(self);
  1334.     self = other;
  1335.  
  1336. // change to the weapon
  1337.     if (!deathmatch)
  1338.         self.weapon = new;
  1339.     else
  1340.         Deathmatch_Weapon (old, new);
  1341.  
  1342.     W_SetCurrentAmmo ();
  1343. };
  1344.  
  1345. /*
  1346. ===============
  1347. DropBackpack
  1348. ===============
  1349. */
  1350. void() DropBackpack =
  1351. {
  1352.     local entity    item;
  1353.  
  1354.     if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
  1355.         return;    // nothing in it
  1356.  
  1357.     item = spawn();
  1358.     item.origin = self.origin - '0 0 24';
  1359.     
  1360.     item.items = self.weapon;
  1361.     if (item.items == IT_AXE)
  1362.         item.netname = "Axe";
  1363.     else if (item.items == IT_SHOTGUN)
  1364.         item.netname = "Shotgun";
  1365.     else if (item.items == IT_SUPER_SHOTGUN)
  1366.         item.netname = "Double-barrelled Shotgun";
  1367.     else if (item.items == IT_NAILGUN)
  1368.         item.netname = "Nailgun";
  1369.     else if (item.items == IT_SUPER_NAILGUN)
  1370.         item.netname = "Super Nailgun";
  1371.     else if (item.items == IT_GRENADE_LAUNCHER)
  1372.         item.netname = "Grenade Launcher";
  1373.     else if (item.items == IT_ROCKET_LAUNCHER)
  1374.         item.netname = "Rocket Launcher";
  1375.     else if (item.items == IT_LIGHTNING)
  1376.         item.netname = "Thunderbolt";
  1377.     else
  1378.         item.netname = "";
  1379.  
  1380.     item.ammo_shells = self.ammo_shells;
  1381.     item.ammo_nails = self.ammo_nails;
  1382.     item.ammo_rockets = self.ammo_rockets;
  1383.     item.ammo_cells = self.ammo_cells;
  1384.  
  1385.     item.velocity_z = 300;
  1386.     item.velocity_x = -100 + (random() * 200);
  1387.     item.velocity_y = -100 + (random() * 200);
  1388.     
  1389.     item.flags = FL_ITEM;
  1390.     item.solid = SOLID_TRIGGER;
  1391.     item.movetype = MOVETYPE_TOSS;
  1392.     setmodel (item, "progs/backpack.mdl");
  1393.     setsize (item, '-16 -16 0', '16 16 56');
  1394.     item.touch = BackpackTouch;
  1395.     
  1396.     item.nextthink = time + 120;    // remove after 2 minutes
  1397.     item.think = SUB_Remove;
  1398. };
  1399.